package 实验四4;

class Buffer {
    private final int[] buffer;
    private int count = 0;
    private int in = 0;
    private int out = 0;

    public Buffer(int size) {
        this.buffer = new int[size];
    }

    public synchronized void produce(int item) throws InterruptedException {
        // 等待缓冲区有空间
        while (count == buffer.length) {
            wait();
        }

        // 添加元素到缓冲区
        buffer[in] = item;
        in = (in + 1) % buffer.length;
        count++;
        System.out.println("Produced: " + item);

        // 通知消费者有新元素
        notifyAll();
    }

    public synchronized int consume() throws InterruptedException {
        // 等待缓冲区有元素
        while (count == 0) {
            wait();
        }

        // 从缓冲区取出元素
        int item = buffer[out];
        out = (out + 1) % buffer.length;
        count--;
        System.out.println("Consumed: " + item);

        // 通知生产者有空间
        notifyAll();
        return item;
    }
}

class Producer implements Runnable {
    private final Buffer buffer;

    public Producer(Buffer buffer) {
        this.buffer = buffer;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                buffer.produce(i);
                Thread.sleep(100); // 模拟生产耗时
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

class Consumer implements Runnable {
    private final Buffer buffer;

    public Consumer(Buffer buffer) {
        this.buffer = buffer;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                int item = buffer.consume();
                Thread.sleep(200); // 模拟消费耗时
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Buffer buffer = new Buffer(5); // 缓冲区大小为5

        Thread producerThread = new Thread(new Producer(buffer));
        Thread consumerThread = new Thread(new Consumer(buffer));

        producerThread.start();
        consumerThread.start();

        // 等待两个线程执行完毕
        try {
            producerThread.join();
            consumerThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}